<!DOCTYPE html><html><head><meta charset="utf-8"><title>Angular - 多级依赖注入器</title><base href="/"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="search" type="application/opensearchdescription+xml" href="assets/opensearch.xml"><link rel="icon" type="image/x-icon" href="assets/images/favicons/favicon.ico"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-194x194.png" sizes="194x194"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-16x16.png" sizes="16x16"><link rel="apple-touch-icon" sizes="144x144" href="assets/images/favicons/favicon-144x144.png"><link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/images/favicons/favicon-144x144.png"><link href="assets/fonts/Material_Icons.css" rel="stylesheet"><link href="assets/fonts/Droid_Sans_Mono.css" rel="stylesheet"><link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"><link rel="manifest" href="pwa-manifest.json"><meta name="theme-color" content="#1976d2"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="translucent"><script async="" src="assets/js/analytics.js"></script><script>!function(e,a,n,t,s,c,g){e.GoogleAnalyticsObject=s,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(n),g=a.getElementsByTagName(n)[0],c.async=1,c.src="assets/js/analytics.js",~e.name.indexOf("NG_DEFER_BOOTSTRAP")||g.parentNode.insertBefore(c,g)}(window,document,"script",0,"ga")</script><script>window.onerror=function(){ga("send","exception",{exDescription:function(e,r,n,a,c){var l;e=e.replace(/^Error: /,""),l=c?c.stack.replace(/^Error: /,"").replace(e+"\n","").replace(/^ +/gm,"").replace(/^at /gm,"").replace(/(?: \(|@)http.+\/([^/)]+)\)?(?:\n|$)/gm,"@$1\n").replace(/ *\(eval code(:\d+:\d+)\)(?:\n|$)/gm,"@???$1\n"):r+":"+(n=n||"?")+":"+(a=a||"?");return(e+"\n"+l).substr(0,150)}.apply(null,arguments),exFatal:!0})}</script><script nomodule="" src="generated/ie-polyfills.min.js"></script><link rel="stylesheet" href="styles.10ba6936decaea45eabb.css"><style>@media screen and (-ms-high-contrast:active){.mat-toolbar{outline:solid 1px}}.mat-toolbar-row,.mat-toolbar-single-row{display:flex;box-sizing:border-box;padding:0 16px;width:100%;flex-direction:row;align-items:center;white-space:nowrap}.mat-toolbar-multiple-rows{display:flex;box-sizing:border-box;flex-direction:column;width:100%}.mat-toolbar-multiple-rows{min-height:64px}.mat-toolbar-row,.mat-toolbar-single-row{height:64px}@media (max-width:599px){.mat-toolbar-multiple-rows{min-height:56px}.mat-toolbar-row,.mat-toolbar-single-row{height:56px}}</style><style>.mat-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px}.mat-icon.mat-icon-inline{font-size:inherit;height:inherit;line-height:inherit;width:inherit}[dir=rtl] .mat-icon-rtl-mirror{transform:scale(-1,1)}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon{display:block}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-icon{margin:auto}</style><style>.mat-button .mat-button-focus-overlay,.mat-icon-button .mat-button-focus-overlay{opacity:0}.mat-button:hover .mat-button-focus-overlay,.mat-stroked-button:hover .mat-button-focus-overlay{opacity:.04}@media (hover:none){.mat-button:hover .mat-button-focus-overlay,.mat-stroked-button:hover .mat-button-focus-overlay{opacity:0}}.mat-button,.mat-flat-button,.mat-icon-button,.mat-stroked-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible}.mat-button::-moz-focus-inner,.mat-flat-button::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-stroked-button::-moz-focus-inner{border:0}.mat-button[disabled],.mat-flat-button[disabled],.mat-icon-button[disabled],.mat-stroked-button[disabled]{cursor:default}.mat-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-button.cdk-program-focused .mat-button-focus-overlay,.mat-flat-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-flat-button.cdk-program-focused .mat-button-focus-overlay,.mat-icon-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-icon-button.cdk-program-focused .mat-button-focus-overlay,.mat-stroked-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-stroked-button.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-button::-moz-focus-inner,.mat-flat-button::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-stroked-button::-moz-focus-inner{border:0}.mat-raised-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1)}.mat-raised-button::-moz-focus-inner{border:0}.mat-raised-button[disabled]{cursor:default}.mat-raised-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-raised-button.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-raised-button::-moz-focus-inner{border:0}._mat-animation-noopable.mat-raised-button{transition:none;animation:none}.mat-stroked-button{border:1px solid currentColor;padding:0 15px;line-height:34px}.mat-fab{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);min-width:0;border-radius:50%;width:56px;height:56px;padding:0;flex-shrink:0}.mat-fab::-moz-focus-inner{border:0}.mat-fab[disabled]{cursor:default}.mat-fab.cdk-keyboard-focused .mat-button-focus-overlay,.mat-fab.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-fab::-moz-focus-inner{border:0}._mat-animation-noopable.mat-fab{transition:none;animation:none}.mat-fab .mat-button-wrapper{padding:16px 0;display:inline-block;line-height:24px}.mat-mini-fab{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);min-width:0;border-radius:50%;width:40px;height:40px;padding:0;flex-shrink:0}.mat-mini-fab::-moz-focus-inner{border:0}.mat-mini-fab[disabled]{cursor:default}.mat-mini-fab.cdk-keyboard-focused .mat-button-focus-overlay,.mat-mini-fab.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-mini-fab::-moz-focus-inner{border:0}._mat-animation-noopable.mat-mini-fab{transition:none;animation:none}.mat-mini-fab .mat-button-wrapper{padding:8px 0;display:inline-block;line-height:24px}.mat-icon-button{padding:0;min-width:0;width:40px;height:40px;flex-shrink:0;line-height:40px;border-radius:50%}.mat-icon-button .mat-icon,.mat-icon-button i{line-height:24px}.mat-button-focus-overlay,.mat-button-ripple.mat-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;border-radius:inherit}.mat-button-focus-overlay{border-radius:inherit;opacity:0;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1)}._mat-animation-noopable .mat-button-focus-overlay{transition:none}@media screen and (-ms-high-contrast:active){.mat-button-focus-overlay{background-color:rgba(255,255,255,.5)}}.mat-button-ripple-round{border-radius:50%;z-index:1}.mat-button .mat-button-wrapper>*,.mat-fab .mat-button-wrapper>*,.mat-flat-button .mat-button-wrapper>*,.mat-icon-button .mat-button-wrapper>*,.mat-mini-fab .mat-button-wrapper>*,.mat-raised-button .mat-button-wrapper>*,.mat-stroked-button .mat-button-wrapper>*{vertical-align:middle}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button{display:block;font-size:inherit;width:2.5em;height:2.5em}@media screen and (-ms-high-contrast:active){.mat-button,.mat-fab,.mat-flat-button,.mat-icon-button,.mat-mini-fab,.mat-raised-button{outline:solid 1px}}</style><style>.mat-drawer-container{position:relative;z-index:1;box-sizing:border-box;-webkit-overflow-scrolling:touch;display:block;overflow:hidden}.mat-drawer-container[fullscreen]{top:0;left:0;right:0;bottom:0;position:absolute}.mat-drawer-container[fullscreen].mat-drawer-opened{overflow:hidden}.mat-drawer-container.mat-drawer-container-explicit-backdrop .mat-drawer-side{z-index:3}.mat-drawer-container.ng-animate-disabled .mat-drawer-backdrop,.mat-drawer-container.ng-animate-disabled .mat-drawer-content,.ng-animate-disabled .mat-drawer-container .mat-drawer-backdrop,.ng-animate-disabled .mat-drawer-container .mat-drawer-content{transition:none}.mat-drawer-backdrop{top:0;left:0;right:0;bottom:0;position:absolute;display:block;z-index:3;visibility:hidden}.mat-drawer-backdrop.mat-drawer-shown{visibility:visible}.mat-drawer-transition .mat-drawer-backdrop{transition-duration:.4s;transition-timing-function:cubic-bezier(.25,.8,.25,1);transition-property:background-color,visibility}@media screen and (-ms-high-contrast:active){.mat-drawer-backdrop{opacity:.5}}.mat-drawer-content{position:relative;z-index:1;display:block;height:100%;overflow:auto}.mat-drawer-transition .mat-drawer-content{transition-duration:.4s;transition-timing-function:cubic-bezier(.25,.8,.25,1);transition-property:transform,margin-left,margin-right}.mat-drawer{position:relative;z-index:4;display:block;position:absolute;top:0;bottom:0;z-index:3;outline:0;box-sizing:border-box;overflow-y:auto;transform:translate3d(-100%,0,0)}@media screen and (-ms-high-contrast:active){.mat-drawer,[dir=rtl] .mat-drawer.mat-drawer-end{border-right:solid 1px currentColor}}@media screen and (-ms-high-contrast:active){.mat-drawer.mat-drawer-end,[dir=rtl] .mat-drawer{border-left:solid 1px currentColor;border-right:none}}.mat-drawer.mat-drawer-side{z-index:2}.mat-drawer.mat-drawer-end{right:0;transform:translate3d(100%,0,0)}[dir=rtl] .mat-drawer{transform:translate3d(100%,0,0)}[dir=rtl] .mat-drawer.mat-drawer-end{left:0;right:auto;transform:translate3d(-100%,0,0)}.mat-drawer-inner-container{width:100%;height:100%;overflow:auto;-webkit-overflow-scrolling:touch}.mat-sidenav-fixed{position:fixed}</style><style>.nav-link.highlight[_ngcontent-c5]{color:#ff0}</style><script charset="utf-8" src="toc-toc-module-ngfactory.36694c537d7ff0b2c081.js"></script><script charset="utf-8" src="default~code-code-example-module-ngfactory~code-code-tabs-module-ngfactory~getting-started-ng-for-ng~82f414e5.c64b8abba8f3b7168616.js"></script><script charset="utf-8" src="default~code-code-example-module-ngfactory~code-code-tabs-module-ngfactory.98830c4eaea3268880de.js"></script><script charset="utf-8" src="code-code-example-module-ngfactory.bb14a03c7095ffd0e7bd.js"></script><script charset="utf-8" src="live-example-live-example-module-ngfactory.fef451c7b16613f97732.js"></script><style>.mat-progress-bar{display:block;height:4px;overflow:hidden;position:relative;transition:opacity 250ms linear;width:100%}._mat-animation-noopable.mat-progress-bar{transition:none;animation:none}.mat-progress-bar .mat-progress-bar-element,.mat-progress-bar .mat-progress-bar-fill::after{height:100%;position:absolute;width:100%}.mat-progress-bar .mat-progress-bar-background{width:calc(100% + 10px)}@media screen and (-ms-high-contrast:active){.mat-progress-bar .mat-progress-bar-background{display:none}}.mat-progress-bar .mat-progress-bar-buffer{transform-origin:top left;transition:transform 250ms ease}@media screen and (-ms-high-contrast:active){.mat-progress-bar .mat-progress-bar-buffer{border-top:solid 5px;opacity:.5}}.mat-progress-bar .mat-progress-bar-secondary{display:none}.mat-progress-bar .mat-progress-bar-fill{animation:none;transform-origin:top left;transition:transform 250ms ease}@media screen and (-ms-high-contrast:active){.mat-progress-bar .mat-progress-bar-fill{border-top:solid 4px}}.mat-progress-bar .mat-progress-bar-fill::after{animation:none;content:'';display:inline-block;left:0}.mat-progress-bar[dir=rtl],[dir=rtl] .mat-progress-bar{transform:rotateY(180deg)}.mat-progress-bar[mode=query]{transform:rotateZ(180deg)}.mat-progress-bar[mode=query][dir=rtl],[dir=rtl] .mat-progress-bar[mode=query]{transform:rotateZ(180deg) rotateY(180deg)}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-fill,.mat-progress-bar[mode=query] .mat-progress-bar-fill{transition:none}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary,.mat-progress-bar[mode=query] .mat-progress-bar-primary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-translate 2s infinite linear;left:-145.166611%}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-primary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary,.mat-progress-bar[mode=query] .mat-progress-bar-secondary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-translate 2s infinite linear;left:-54.888891%;display:block}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-secondary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=buffer] .mat-progress-bar-background{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-background-scroll 250ms infinite linear;display:block}.mat-progress-bar._mat-animation-noopable .mat-progress-bar-background,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-buffer,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-fill,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-fill::after,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-primary,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-primary.mat-progress-bar-fill::after,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-secondary,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-secondary.mat-progress-bar-fill::after{animation:none;transition:none}@keyframes mat-progress-bar-primary-indeterminate-translate{0%{transform:translateX(0)}20%{animation-timing-function:cubic-bezier(.5,0,.70173,.49582);transform:translateX(0)}59.15%{animation-timing-function:cubic-bezier(.30244,.38135,.55,.95635);transform:translateX(83.67142%)}100%{transform:translateX(200.61106%)}}@keyframes mat-progress-bar-primary-indeterminate-scale{0%{transform:scaleX(.08)}36.65%{animation-timing-function:cubic-bezier(.33473,.12482,.78584,1);transform:scaleX(.08)}69.15%{animation-timing-function:cubic-bezier(.06,.11,.6,1);transform:scaleX(.66148)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-secondary-indeterminate-translate{0%{animation-timing-function:cubic-bezier(.15,0,.51506,.40969);transform:translateX(0)}25%{animation-timing-function:cubic-bezier(.31033,.28406,.8,.73371);transform:translateX(37.65191%)}48.35%{animation-timing-function:cubic-bezier(.4,.62704,.6,.90203);transform:translateX(84.38617%)}100%{transform:translateX(160.27778%)}}@keyframes mat-progress-bar-secondary-indeterminate-scale{0%{animation-timing-function:cubic-bezier(.15,0,.51506,.40969);transform:scaleX(.08)}19.15%{animation-timing-function:cubic-bezier(.31033,.28406,.8,.73371);transform:scaleX(.4571)}44.15%{animation-timing-function:cubic-bezier(.4,.62704,.6,.90203);transform:scaleX(.72796)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-background-scroll{to{transform:translateX(-8px)}}</style><script charset="utf-8" src="21.d3ebf64aa7b6d3a4b8f6.js"></script></head><body><aio-shell ng-version="7.0.0" class="mode-stable sidenav-open page-guide-hierarchical-dependency-injection folder-guide view-SideNav aio-notification-show"><div id="top-of-page"></div><mat-toolbar class="app-toolbar no-print mat-toolbar mat-primary mat-toolbar-multiple-rows" color="primary"><mat-toolbar-row class="notification-container mat-toolbar-row"><aio-notification expirationdate="2019-03-01" notificationid="survey-february-2019" class="ng-tns-c2-0 ng-trigger ng-trigger-hideAnimation"><span class="content"><a href="http://bit.ly/angular-survey-2019" target="_blank"><mat-icon aria-label="Announcement" class="icon mat-icon" role="img" svgicon="insert_comment" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></mat-icon><span class="message"><b>填写这份《一分钟调查》</b>，帮我们（开发组）做得更好！</span><span class="action-button">去填写</span></a></span><button class="close-button mat-icon-button" aria-label="Close" mat-icon-button=""><span class="mat-button-wrapper"><mat-icon aria-label="Dismiss notification" class="mat-icon ng-tns-c2-0" role="img" svgicon="close" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></mat-icon></span><div class="mat-button-ripple mat-ripple mat-button-ripple-round" matripple=""></div><div class="mat-button-focus-overlay"></div></button></aio-notification></mat-toolbar-row><mat-toolbar-row class="mat-toolbar-row"><button class="hamburger mat-button" mat-button="" title="Docs menu"><span class="mat-button-wrapper"><mat-icon class="mat-icon" role="img" svgicon="menu" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></svg></mat-icon></span><div class="mat-button-ripple mat-ripple" matripple=""></div><div class="mat-button-focus-overlay"></div></button><a class="nav-link home" href="/"><img alt="Home" height="40" src="assets/images/logos/angular/logo-nav@2x.png" title="Home" width="150" class="ng-star-inserted"></a><aio-top-menu _nghost-c5="" class="ng-star-inserted"><ul _ngcontent-c5="" role="navigation"><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="features" title="特性"><span _ngcontent-c5="" class="nav-link-inner">特性</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="docs" title="文档"><span _ngcontent-c5="" class="nav-link-inner">文档</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="resources" title="资源"><span _ngcontent-c5="" class="nav-link-inner">资源</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="events" title="会议"><span _ngcontent-c5="" class="nav-link-inner">会议</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="https://blog.angular.io/" title="博客"><span _ngcontent-c5="" class="nav-link-inner">博客</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="translations/cn/home" title="关于中文版"><span _ngcontent-c5="" class="nav-link-inner">关于中文版</span></a></li></ul></aio-top-menu><aio-search-box class="search-container"><input aria-label="search" placeholder="搜索" type="search"></aio-search-box><div class="toolbar-external-icons-container"><a aria-label="Angular on twitter" href="https://twitter.com/angular" title="Twitter"><mat-icon class="mat-icon" role="img" svgicon="logos:twitter" aria-hidden="true"><svg focusable="false" viewBox="0 0 50 59" xmlns="http://www.w3.org/2000/svg"><path d="M50,9.3c-1.8,0.8-3.8,1.4-5.9,1.6c2.1-1.3,3.7-3.3,4.5-5.7c-2,1.2-4.2,2-6.5,2.5c-1.9-2-4.5-3.2-7.5-3.2c-5.7,0-10.3,4.6-10.3,10.3c0,0.8,0.1,1.6,0.3,2.3C16.1,16.7,8.5,12.6,3.5,6.4c-0.9,1.5-1.4,3.3-1.4,5.2c0,3.6,1.8,6.7,4.6,8.5C5,20,3.4,19.6,2,18.8c0,0,0,0.1,0,0.1c0,5,3.5,9.1,8.2,10.1c-0.9,0.2-1.8,0.4-2.7,0.4c-0.7,0-1.3-0.1-1.9-0.2c1.3,4.1,5.1,7,9.6,7.1c-3.5,2.8-7.9,4.4-12.7,4.4c-0.8,0-1.6,0-2.4-0.1c4.5,2.9,9.9,4.6,15.7,4.6c18.9,0,29.2-15.6,29.2-29.2c0-0.4,0-0.9,0-1.3C46.9,13.2,48.6,11.4,50,9.3z"></path></svg></mat-icon></a><a aria-label="Angular on github" href="https://github.com/angular/angular" title="GitHub"><mat-icon class="mat-icon" role="img" svgicon="logos:github" aria-hidden="true"><svg focusable="false" viewBox="0 0 51.8 50.4" xmlns="http://www.w3.org/2000/svg"><path d="M25.9,0.2C11.8,0.2,0.3,11.7,0.3,25.8c0,11.3,7.3,20.9,17.5,24.3c1.3,0.2,1.7-0.6,1.7-1.2c0-0.6,0-2.6,0-4.8c-7.1,1.5-8.6-3-8.6-3c-1.2-3-2.8-3.7-2.8-3.7c-2.3-1.6,0.2-1.6,0.2-1.6c2.6,0.2,3.9,2.6,3.9,2.6c2.3,3.9,6,2.8,7.5,2.1c0.2-1.7,0.9-2.8,1.6-3.4c-5.7-0.6-11.7-2.8-11.7-12.7c0-2.8,1-5.1,2.6-6.9c-0.3-0.7-1.1-3.3,0.3-6.8c0,0,2.1-0.7,7,2.6c2-0.6,4.2-0.9,6.4-0.9c2.2,0,4.4,0.3,6.4,0.9c4.9-3.3,7-2.6,7-2.6c1.4,3.5,0.5,6.1,0.3,6.8c1.6,1.8,2.6,4.1,2.6,6.9c0,9.8-6,12-11.7,12.6c0.9,0.8,1.7,2.4,1.7,4.7c0,3.4,0,6.2,0,7c0,0.7,0.5,1.5,1.8,1.2c10.2-3.4,17.5-13,17.5-24.3C51.5,11.7,40.1,0.2,25.9,0.2z"></path></svg></mat-icon></a></div></mat-toolbar-row></mat-toolbar><mat-sidenav-container class="sidenav-container mat-drawer-container mat-sidenav-container mat-drawer-transition has-floating-toc" role="main"><div class="mat-drawer-backdrop ng-star-inserted"></div><div class="cdk-visually-hidden cdk-focus-trap-anchor"></div><mat-sidenav class="sidenav mat-drawer mat-sidenav ng-tns-c7-1 ng-trigger ng-trigger-transform mat-drawer-side ng-star-inserted" tabindex="-1" style="transform:none;visibility:visible"><div class="mat-drawer-inner-container"><aio-nav-menu><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="guide/quickstart" title="对 Angular 和 Angular CLI 基础知识的简短介绍" target="_self">快速上手</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="此《英雄指南》教程会带你用 TypeScript 一步步创建一个 Angular 应用。" aria-pressed="false">教程<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial" title="《英雄指南》教程简介" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt0" title="创建应用的外壳" target="_self">应用的“外壳”</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt1" title="第一部分：构建一个简单的英雄编辑器" target="_self">1. 英雄编辑器</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt2" title="第二部分：构建一个主从结构的页面，用于展现英雄列表。" target="_self">2. 显示英雄列表</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt3" title="第三部分：把主从结构的页面重构成多个组件。" target="_self">3. 主从组件</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt4" title="第四部分：创建一个可复用的服务来管理英雄数据。" target="_self">4. 服务</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt5" title="第五部分：添加 Angular 路由器，并且学习在视图之间导航。" target="_self">5. 路由</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt6" title="第六部分：通过 HTTP 来获取并保存英雄数据。" target="_self">6. HTTP</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 expanded selected ng-star-inserted" type="button" title="学习 Angular 的核心知识" aria-pressed="true">核心知识<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 expanded selected"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 应用的基本构造块。" aria-pressed="false">架构<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture" title="Angular 应用的基本构造块" target="_self">架构概览</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-modules" title="关于模块。" target="_self">模块（NgModule）简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-components" title="关于组件、模板和视图。" target="_self">组件简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-services" title="关于服务与依赖注入。" target="_self">服务与 DI 简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-next-steps" title="学完基础知识之后……" target="_self">后续步骤</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="使用数据绑定构建动态视图" aria-pressed="false">组件与模板<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/displaying-data" title="属性绑定可以帮助应用把数据显示在界面上" target="_self">显示数据</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/template-syntax" title="学习如何写模板，以便借助数据绑定机制显示数据并响应事件。" target="_self">模板语法</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/user-input" title="用户输入会触发 DOM 事件。Angular 会通过事件绑定来监听那些事件，并把修改后的值传回应用的组件和模型中。" target="_self">用户输入</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/lifecycle-hooks" title="Angular 调用指令和组件的生命周期钩子函数，包括它的创建、变更和销毁时。" target="_self">生命周期钩子</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/component-interaction" title="在不同的指令和组件之间共享信息" target="_self">组件交互</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/component-styles" title="添加专属于某个组件的样式" target="_self">组件样式</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/elements" title="把组件转换成自定义元素。" target="_self">Angular 自定义元素</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dynamic-component-loader" title="动态加载组件" target="_self">动态组件</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/attribute-directives" title="属性型指令把行为添加到现有元素上。" target="_self">属性型指令</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/structural-directives" title="结构型指令可以操纵页面的布局" target="_self">结构型指令</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/pipes" title="管道可以在模板中转换显示的内容。" target="_self">管道</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 的表单" aria-pressed="false">表单<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/forms-overview" title="表单可以创建集中、高效、引人注目的输入体验。Angular 表单可以协调一组数据绑定控件，跟踪变更，验证输入，并表达错误信息。" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/reactive-forms" title="使用 FormBuilder、表单组和表单数组创建响应式表单。" target="_self">响应式表单</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/forms" title="使用指令和 Angular 模板语法创建模板驱动表单。" target="_self">模板驱动表单</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/form-validation" title="验证用户的表单输入" target="_self">表单验证</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dynamic-form" title="使用 FormGroup 渲染动态表单。" target="_self">动态表单</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Observable 与 RxJS" aria-pressed="false">Observable 与 RxJS<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/observables" title="" target="_self">可观察对象(Observable)</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/rx-library" title="" target="_self">RxJS 库</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/observables-in-angular" title="" target="_self">Angular 中的可观察对象</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/practical-observable-usage" title="" target="_self">用法实战</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/comparing-observables" title="" target="_self">与其它技术的比较</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/bootstrapping" title="在应用的根模块（AppModule）中告诉 Angular 如何构造并引导引用。" target="_self">引导启动</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 中的模块" aria-pressed="false">NgModule<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodules" title="使用 NgModule 让你的应用更高效" target="_self">NgModule 简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-vs-jsmodule" title="JavaScript 模块和 NgModule 之间的差异" target="_self">JS 模块 vs NgModule</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/frequent-ngmodules" title="介绍最常用的 NgModule" target="_self">常用模块</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/module-types" title="介绍特性模块的几种类型" target="_self">特性模块的分类</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/entry-components" title="关于 Angular 中入口组件的一切" target="_self">入口组件</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/feature-modules" title="创建特性模块，以组织你的代码" target="_self">特性模块</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/providers" title="服务提供商与 NgModule" target="_self">服务提供商</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/singleton-services" title="创建单例服务" target="_self">单例服务</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/lazy-loading-ngmodules" title="惰性加载模块，以提高应用的性能" target="_self">惰性加载的特性模块</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/sharing-ngmodules" title="共享 NgModule 让你的应用现代化。" target="_self">共享 NgModule</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-api" title="理解 NgModule 的那些细节。" target="_self">NgModule API</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-faq" title="回答关于 NgModules 的常见问题。" target="_self">NgModule 常见问题</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 expanded selected ng-star-inserted" type="button" title="依赖注入：创建并注入各种服务。" aria-pressed="true">依赖注入<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 expanded selected"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection" title="Angular 的依赖注入系统能够为 Angular 创建的类创建并交付它们所依赖的服务。" target="_self">Angular 依赖注入</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 expanded selected ng-star-inserted" style="position:relative" href="guide/hierarchical-dependency-injection" title="与组件树平行的注入器树，并支持嵌套的依赖。" target="_self">多级注入器</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-providers" title="各种提供商类型的更多知识。" target="_self">DI 提供商</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-in-action" title="依赖注入的使用技巧" target="_self">DI 实战</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-navtree" title="使用注入器树来查找父组件。" target="_self">浏览组件树</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/http" title="通过 HTTP 协议与远程服务器对话。" target="_self">HttpClient</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/router" title="揭示如何通过 Angular 路由进行基本的屏幕导航。" target="_self">路由与导航</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 动画系统指南" aria-pressed="false">动画<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/animations" title="Angular 动画的基础技术。" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/transition-and-triggers" title="转场与触发器的高级技术。" target="_self">转场与触发器</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/complex-animation-sequences" title="复杂的 Angular 动画序列。" target="_self">复杂序列</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/reusable-animations" title="创建可复用的动画。" target="_self">可复用动画</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/route-animations" title="为路由提供转场动画。" target="_self">路由转场动画</a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="把 Angular 用到你的实际工作中的一些技巧" aria-pressed="false">其它技术<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/security" title="Angular 应用开发中的安全技术。" target="_self">安全</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/i18n" title="把应用模板中的文本翻译成多种语言。" target="_self">国际化 (i18n)</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular Service Worker: 控制应用资源的缓存。" aria-pressed="false">Service Worker 与 PWA<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-intro" title="Angular 对 Service Worker 的实现提升了慢速或不稳定的网络连接下的用户体验。" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-getting-started" title="在 CLI 项目中启用 Service Worker，并在浏览器中查看效果。" target="_self">快速起步</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-communications" title="那些能让你和 Angular 的 Service Worker 通讯的服务类。" target="_self">与 Service Worker 通讯</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-devops" title="使用 Service Worker 运行应用、管理应用更新、调试以及杀掉正在运行的应用。" target="_self">生产环境下的 Service Worker</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-config" title="配置 Service Worker 的缓存行为。" target="_self">Service Worker 配置</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/universal" title="使用 Angular Universal 在服务端渲染 HTML。" target="_self">服务端渲染</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="把 AngularJS 应用增量式的升级到 Angular。" aria-pressed="false">从 AngularJS 升级<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/upgrade" title="把 AngularJS 应用增量式的升级到 Angular。" target="_self">升级步骤</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/upgrade-performance" title="用更灵活的方式把 AngularJS 升级到 Angular" target="_self">更关注性能的升级方式</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ajs-quick-reference" title="学习如何把 AngularJS 的概念映射到 Angular 中。" target="_self">AngularJS 与 Angular 的概念对照</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="使用共享库扩展 Angular" aria-pressed="false">Angular 库开发<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/libraries" title="理解何时以及如何使用和创建库。" target="_self">库概览</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/using-libraries" title="把已发布的库集成进你的应用中。" target="_self">使用已发布的库</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/creating-libraries" title="通过创建、发布和使用你自己的库来扩展 Angular" target="_self">创建库</a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="关于环境搭建、构建、测试、部署环境与工具的信息。" aria-pressed="false">环境搭建与部署<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/file-structure" title="Angular 工作区在文件系统中是怎样的。" target="_self">项目文件结构</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/workspace-config" title="&quot;angular.json&quot; 包含供 CLI 命令使用的工作区和项目默认配置。" target="_self">工作区配置</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/npm-packages" title="开发期间和运行期间所需的 npm 包的说明。" target="_self">npm 包</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/typescript-configuration" title="给 Angular 开发者的 TypeScript 配置。" target="_self">TypeScript 配置</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/aot-compiler" title="了解为何以及如何使用预先（AOT）编译器。" target="_self">预先（AOT）编译</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/build" title="构建应用及为应用启动开发服务器。" target="_self">构建与运行</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/testing" title="测试 Angular 应用的技巧与实践。" target="_self">测试</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/deployment" title="了解如何部署 Angular 应用。" target="_self">发布</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/browser-support" title="浏览器支持与腻子脚本指南。" target="_self">浏览器支持</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="整合开发环境和工具。" aria-pressed="false">开发工具集成<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/language-service" title="使用 Angular 语言服务加速开发。" target="_self">语言服务</a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="Angular 的版本发布实践、更新与升级。" aria-pressed="false">发布信息<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/updating" title="如何把 Angular 应用和库升级到最新版本。" target="_self">保持最新</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/releases" title="Angular 的版本、发布、支持、弃用策略与实践。" target="_self">Angular 发布策略与实践</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="Angular 语法、编码、术语汇总。" aria-pressed="false">快捷手册<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/cheatsheet" title="关于 Angular 常用编码技术的快速指南。" target="_self">速查表</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/styleguide" title="写出 Angular 风格的程序" target="_self">风格指南</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/glossary" title="Angular 中最重要的词汇的简要定义。" target="_self">词汇表</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="Angular CLI 命令参考手册。" aria-pressed="false">CLI 命令<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli" title="CLI 工具介绍、命令、语法" target="_self">概览</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/add" title="ng add." target="_self">ng add</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/build" title="ng build." target="_self">ng build</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/config" title="ng config." target="_self">ng config</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/doc" title="ng doc." target="_self">ng doc</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/e2e" title="ng e2e." target="_self">ng e2e</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/generate" title="ng generate." target="_self">ng generate</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/help" title="ng help." target="_self">ng help</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/lint" title="ng lint." target="_self">ng lint</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/new" title="ng new." target="_self">ng new</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/run" title="ng run." target="_self">ng run</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/serve" title="ng serve." target="_self">ng serve</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/test" title="ng test." target="_self">ng test</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/update" title="ng update." target="_self">ng update</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/version" title="ng version." target="_self">ng version</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/xi18n" title="ng xi18n." target="_self">ng xi18n</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="api" title="关于 Angular 中类和值的详细信息。" target="_self">API 参考手册</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><div class="mat-divider ng-star-inserted" style="margin:4px 20px;border-top:1px solid #d3d3d3"></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng-china.org" title="2018 ngChina 开发者大会" target="_blank">2018 ngChina @ 杭州<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://github.com/ng-docs/ng-docs.github.io/issues" title="github 上的中文互助问答区" target="_blank">互助问答<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://material.angular.cn" title="Angular Material 组件库的中文文档" target="_blank">官方 Material 组件库<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng.ant.design/" title="Ant Design 的 Angular 实现，服务于企业级后台产品。" target="_blank">ng-zorro 组件库<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng.mobile.ant.design/" title="Ant Design Mobile 的 Angular 实现，服务于无线产品。" target="_blank">ng-zorro mobile 组件库<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item></aio-nav-menu><div class="doc-version"><aio-select><div class="form-select-menu"><button class="form-select-button"><strong></strong>stable (v8.0.0-beta.4)</button></div></aio-select></div></div></mat-sidenav><div class="cdk-visually-hidden cdk-focus-trap-anchor"></div><mat-sidenav-content cdkscrollable="" class="mat-drawer-content mat-sidenav-content ng-star-inserted" style="margin-left:260px"><main class="sidenav-content" role="main" id="guide-hierarchical-dependency-injection"><aio-mode-banner></aio-mode-banner><aio-doc-viewer class=""><div style="opacity:1"><div class="github-links"><a href="https://github.com/angular/angular-cn/edit/aio/aio/content/guide/hierarchical-dependency-injection.md?message=docs%3A%20请简述你的修改..." aria-label="提供编辑建议" title="提供编辑建议"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a></div><div class="content"><h1 id="hierarchical-dependency-injectors" translation-result="on">多级依赖注入器<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#hierarchical-dependency-injectors"><i class="material-icons">link</i></a></h1><aio-toc class="embedded" ng-version="7.0.0"><div class="toc-inner no-print collapsed ng-star-inserted"><button aria-label="Expand/collapse contents" class="toc-heading embedded secondary ng-star-inserted" title="Expand/collapse contents" type="button" aria-pressed="false">目录<mat-icon class="rotating-icon mat-icon collapsed" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><ul class="toc-list embedded"><li title="在哪里配置提供商link" class="h2 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#where-to-configure-providers">在哪里配置提供商</a></li><li title="在 @Injectable 级进行配置link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#injectable-level-configuration">在 @Injectable 级进行配置</a></li><li title="@NgModule 级注入器link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#ngmodule-level-injectors">@NgModule 级注入器</a></li><li title="@Component 级注入器link" class="h3 secondary ng-star-inserted"><a href="guide/hierarchical-dependency-injection#component-level-injectors">@Component 级注入器</a></li><li title="元素注入器link" class="h3 secondary ng-star-inserted"><a href="guide/hierarchical-dependency-injection#element-injectors">元素注入器</a></li><li title="注入器冒泡link" class="h2 secondary ng-star-inserted"><a href="guide/hierarchical-dependency-injection#injector-bubbling">注入器冒泡</a></li><li title="组件注入器link" class="h2 secondary ng-star-inserted"><a href="guide/hierarchical-dependency-injection#component-injectors">组件注入器</a></li><li title="场景：服务隔离link" class="h3 secondary ng-star-inserted"><a href="guide/hierarchical-dependency-injection#scenario-service-isolation">场景：服务隔离</a></li><li title="场景：多重编辑会话link" class="h3 secondary ng-star-inserted"><a href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions">场景：多重编辑会话</a></li><li title="场景：专门的提供商link" class="h3 secondary ng-star-inserted"><a href="guide/hierarchical-dependency-injection#scenario-specialized-providers">场景：专门的提供商</a></li></ul><button aria-label="Expand/collapse contents" class="toc-more-items embedded material-icons collapsed ng-star-inserted" title="Expand/collapse contents" type="button" aria-pressed="false"></button></div></aio-toc><h1 translation-origin="off" id="hierarchical-dependency-injectors">Hierarchical Dependency Injectors<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#hierarchical-dependency-injectors"><i class="material-icons">link</i></a></h1><p translation-result="on">Angular 的依赖注入系统是<em>多级的</em>。 实际上，应用程序中有一个与组件树平行的注入器树（译注：平行是指结构完全相同且一一对应）。 你可以在组件树中的任何级别上重新配置注入器。</p><p translation-origin="off">The Angular dependency injection system is <em>hierarchical</em>. There is a tree of injectors that parallels an app's component tree. You can reconfigure the injectors at any level of that component tree.</p><p translation-result="on">本文将带你浏览这个体系，并告诉你要如何善用它。 这里用到的例子基于这个<live-example ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html" title="在线例子">在线例子</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>。</p><p translation-origin="off">This guide explores this system and how to use it to your advantage. It uses examples based on this<live-example ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html" title="在线例子">在线例子</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>.</p><a id="ngmodule-vs-comp"></a> <a id="where-to-register"></a><h2 id="where-to-configure-providers" translation-result="on">在哪里配置提供商<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#where-to-configure-providers"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="where-to-configure-providers">Where to configure providers<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#where-to-configure-providers"><i class="material-icons">link</i></a></h2><p translation-result="on">你可以为注入器树中不同的注入器分别配置提供商。 所有运行中的应用都会共享同一个内部的平台级注入器。 <code>AppModule</code> 上的注入器是全应用级注入器树的根节点，在 NgModule 中，指令级的注入器会遵循组件树的结构。</p><p translation-origin="off">You can configure providers for different injectors in the injector hierarchy. An internal platform-level injector is shared by all running apps. The <code>AppModule</code> injector is the root of an app-wide injector hierarchy, and within an NgModule, directive-level injectors follow the structure of the component hierarchy.</p><p translation-result="on">对于在哪里配置提供商的不同选择会带来一些差异：最终包的大小、服务的<em>范围</em>和服务的<em>生命周期</em>。</p><p translation-origin="off">The choices you make about where to configure providers lead to differences in the final bundle size, service <em>scope</em>, and service <em>lifetime</em>.</p><p translation-result="on">当你在服务自身的 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 装饰器中指定提供商时（通常在应用的根一级），CLI 生产模式构建时所用的优化工具可以执行<em>摇树优化</em>，它会移除没有用过的那些服务。摇树优化生成的包会更小。</p><p translation-origin="off">When you specify providers in the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> decorator of the service itself (typically at the app root level), optimization tools such as those used by the CLI's production builds can perform <em>tree shaking</em>, which removes services that aren't used by your app. Tree shaking results in smaller bundle sizes.</p><ul><li><p translation-result="on">要了解更多，参见<a href="guide/dependency-injection-providers#tree-shakable-providers">可摇树优化的提供商</a>。</p><p translation-origin="off">Learn more about <a href="guide/dependency-injection-providers#tree-shakable-providers">tree-shakable providers</a>.</p></li></ul><p translation-result="on">你可能会在应用程序的许多地方注入 <code>UserService</code>，并希望每次注入的都是服务的同一个实例。这种情况下，通过 <code>root</code> 来提供 <code>UserService</code> 就是不错的选择，而且这也是 <a href="cli">Angular CLI</a> 为应用生成服务时的默认选项。</p><p translation-origin="off">You're likely to inject <code>UserService</code> in many places throughout the app and will want to inject the same service instance every time. Providing <code>UserService</code> through the <code>root</code> injector is a good choice, and is the default that the <a href="cli">Angular CLI</a> uses when you generate a service for your app.</p><div class="alert is-helpful"><header translation-result="on">平台注入器</header><header translation-origin="off">Platform injector</header><p translation-result="on">当使用 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>:'root'</code> 时，你是在配置<em>应用</em>的根注入器，也就是 <code>AppModule</code> 的注入器。 整个注入器树的真正的根是<em>平台注入器</em>，它是根注入器的父节点。 这可以让多个应用共享同一套平台配置。比如，无论你正在运行多少个应用，一个浏览器窗口都只有一个地址栏。</p><p translation-origin="off">When you use <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>:'root'</code>, you are configuring the root injector for the <em>app</em>, which is the injector for <code>AppModule</code>. The actual root of the entire injector hierarchy is a <em>platform injector</em> that is the parent of app-root injectors. This allows multiple apps to share a platform configuration. For example, a browser has only one URL bar, no matter how many apps you have running.</p><p translation-result="on">平台注入器是在启动期间内部使用的，用于配置与平台相关的依赖项。通过在调用 <code><a href="api/platform-browser/platformBrowser" class="code-anchor">platformBrowser</a>()</code> 函数时提供 <code>extraProviders</code> 参数，你可以在平台级配置更多与平台相关的提供商。</p><p translation-origin="off">The platform injector is used internally during bootstrap, to configure platform-specific dependencies. You can configure additional platform-specific providers at the platform level by supplying <code>extraProviders</code> using the <code><a href="api/platform-browser/platformBrowser" class="code-anchor">platformBrowser</a>()</code> function.</p><p translation-result="on">要了解借助注入器树解析依赖项的更多信息，参见<a href="https://blog.angularindepth.com/angular-dependency-injection-and-tree-shakeable-tokens-4588a8f70d5d">你所不知道的 Angular 依赖注入树</a>。</p><p translation-origin="off">Learn more about dependency resolution through the injector hierarchy: <a href="https://blog.angularindepth.com/angular-dependency-injection-and-tree-shakeable-tokens-4588a8f70d5d">What you always wanted to know about Angular Dependency Injection tree</a></p></div><p translation-result="on"><em>NgModule 级</em>的提供商可以在 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> <code>providers</code> 元数据中指定，也可以在 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 的 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 选项中指定某个模块类（但根模块 <code>AppModule</code> 除外）。</p><p translation-origin="off"><em>NgModule-level</em> providers can be specified with <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> <code>providers</code> metadata option, or in the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> option (with some module other than the root <code>AppModule</code>).</p><p translation-result="on">如果某个模块是<a href="guide/lazy-loading-ngmodules">惰性加载</a>的，那么请使用 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 的 <code>provides</code> 选项。加载那个模块时，就会用这里的提供商来配置模块本身的注入器，而 Angular 会为该模块中创建的任何类注入相应的服务。如果你使用了 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 中的 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>: MyLazyloadModule</code> 选项，那么如果该提供商没有在别处用过，就可以在编译期间把它摇树优化掉。</p><p translation-origin="off">Use the <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> <code>providers</code> option if a module is <a href="guide/lazy-loading-ngmodules">lazy loaded</a>. The module's own injector is configured with the provider when that module is loaded, and Angular can inject the corresponding services in any class it creates in that module. If you use the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> option <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>: MyLazyloadModule</code>, the provider could be shaken out at compile time, if it is not used anywhere else in the app.</p><ul><li><p translation-result="on">欲知详情，参见<a href="guide/dependency-injection-providers#tree-shakable-providers">可摇树优化的提供商</a>。</p><p translation-origin="off">Learn more about <a href="guide/dependency-injection-providers#tree-shakable-providers">tree-shakable providers</a>.</p></li></ul><p translation-result="on">无论对于根级注入器还是模块级注入器，服务实例的生存期都和应用或模块本身相同。Angular 可以把这个服务实例注入到任何需要它的类中。</p><p translation-origin="off">For both root-level and module-level injectors, a service instance lives for the life of the app or module, and Angular injects this one service instance in every class that needs it.</p><p translation-result="on"><em>组件级</em>提供商为每个组件实例配置自己的注入器。 Angular 只能把相应的服务注入到该组件实例或其下级组件实例中，而不能把这个服务实例注入到其它地方。</p><p translation-origin="off"><em>Component-level</em> providers configure each component instance's own injector. Angular can only inject the corresponding services in that component instance or one of its descendant component instances. Angular can't inject the same service instance anywhere else.</p><p translation-result="on">组件提供的服务具有受限的生命周期。 该组件的每个新实例都会获得自己的一份服务实例。 当销毁组件实例时，服务实例也会被同时销毁。</p><p translation-origin="off">A component-provided service may have a limited lifetime. Each new instance of the component gets its own instance of the service. When the component instance is destroyed, so is that service instance.</p><p translation-result="on">在这个范例应用中，应用一启动就会创建 <code>HeroComponent</code> 的实例，而且永不销毁，所以由 <code>HeroComponent</code> 创建的 <code>HeroService</code> 的实例的生命周期也和应用相同。 如果你要把 <code>HeroService</code> 的访问权限制到 <code>HeroComponent</code> 及其内嵌的 <code>HeroListComponent</code> 中，可以通过修改 <code>HeroComponent</code> 的元数据，来要求在组件级提供 <code>HeroService</code>。</p><p translation-origin="off">In our sample app, <code>HeroComponent</code> is created when the application starts and is never destroyed, so the <code>HeroService</code> instance created for <code>HeroComponent</code> lives for the life of the app. If you want to restrict <code>HeroService</code> access to <code>HeroComponent</code> and its nested <code>HeroListComponent</code>, provide <code>HeroService</code> at the component level, in <code>HeroComponent</code> metadata.</p><ul><li><p translation-result="on">参见稍后的<a href="guide/hierarchical-dependency-injection#component-injectors">组件级注入的例子</a>。</p><p translation-origin="off">See more <a href="guide/hierarchical-dependency-injection#component-injectors">examples of component-level injection</a> below.</p></li></ul><a id="register-providers-injectable"></a><h3 id="injectable-level-configuration" translation-result="on">在 @Injectable 级进行配置<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#injectable-level-configuration"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="injectable-level-configuration">@Injectable-level configuration<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#injectable-level-configuration"><i class="material-icons">link</i></a></h3><p translation-result="on"><code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 装饰器会标出每个服务类。服务类的元数据选项 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 会指定一个注入器（通常为 <code>root</code> 来用被装饰的类作为该服务的提供商。 当可注入的类向 <code>root</code> 注入器提供了自己的服务时，任何导入了该类的地方都能使用这个服务。</p><p translation-origin="off">The <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> decorator identifies every service class. The <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> metadata option for a service class configures a specific injector (typically <code>root</code>) to use the decorated class as a provider of the service. When an injectable class provides its own service to the <code>root</code> injector, the service is available anywhere the class is imported.</p><p translation-result="on">下面的例子使用类上的 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 装饰器为 <code>HeroService</code> 配置了提供商。</p><p translation-origin="off">The following example configures a provider for <code>HeroService</code> using the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> decorator on the class.</p><code-example path="dependency-injection/src/app/heroes/hero.service.0.ts" header="src/app/heroes/heroes.service.ts" linenums="false" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Injectable" class="code-anchor">Injectable</a> } from '@angular/core'; @<a href="api/core/Injectable" class="code-anchor">Injectable</a>({ <a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>: 'root', }) export class HeroService { constructor() { } }</div><header class="ng-star-inserted">src/app/heroes/heroes.service.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/heroes/heroes.service.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Injectable" class="code-anchor"><span class="typ">Injectable</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Injectable" class="code-anchor"><span class="lit">Injectable</span></a><span class="pun">({</span><span class="pln">
  </span><a href="api/core/Injectable#providedIn" class="code-anchor"><span class="pln">providedIn</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">'root'</span><span class="pun">,</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HeroService</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">这个配置项告诉 Angular，要由此应用的根注入器负责通过调用 <code>HeroService</code> 的构造函数来创建它的实例。 并让该实例在整个应用程序中可用。</p><p translation-origin="off">This configuration tells Angular that the app's root injector is responsible for creating an instance of <code>HeroService</code> by invoking its constructor, and for making that instance available across the application.</p><p translation-result="on">典型的方式是通过应用的根注入器来提供服务，当 CLI 生成新的服务时，也会自动为你设置为这种方式。 不过，你有时候可能不希望通过根注入器提供服务。比如，你可能会希望用户显式的选择如何使用该服务。</p><p translation-origin="off">Providing a service with the app's root injector is a typical case, and the CLI sets up this kind of a provider automatically for you when generating a new service. However, you might not always want to provide your service at the root level. You might, for instance, want users to explicitly opt-in to using the service.</p><p translation-result="on">除了指定给 <code>root</code> 注入器之外，你还可以把 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 设置为某个特定的 NgModule。</p><p translation-origin="off">Instead of specifying the <code>root</code> injector, you can set <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> to a specific NgModule.</p><p translation-result="on">比如，在下面的代码片段中，<code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 装饰器配置了一个提供商，它能用于 <code>HeroModule</code> 包含的所有注入器中。</p><p translation-origin="off">For example, in the following excerpt, the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> decorator configures a provider that is available in any injector that includes the <code>HeroModule</code>.</p><code-example path="dependency-injection/src/app/heroes/hero.service.4.ts" header="src/app/heroes/hero.service.ts" linenums="false" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Injectable" class="code-anchor">Injectable</a> } from '@angular/core'; import { HeroModule } from './hero.module'; import { HEROES } from './mock-heroes'; @<a href="api/core/Injectable" class="code-anchor">Injectable</a>({ // we declare that this service should be created // by any injector that includes HeroModule. <a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a>: HeroModule, }) export class HeroService { getHeroes() { return HEROES; } }</div><header class="ng-star-inserted">src/app/heroes/hero.service.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/heroes/hero.service.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Injectable" class="code-anchor"><span class="typ">Injectable</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroModule</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero.module'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> HEROES </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./mock-heroes'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Injectable" class="code-anchor"><span class="lit">Injectable</span></a><span class="pun">({</span><span class="pln">
  </span><span class="com">// we declare that this service should be created</span><span class="pln">
  </span><span class="com">// by any injector that includes HeroModule.</span><span class="pln">
  </span><a href="api/core/Injectable#providedIn" class="code-anchor"><span class="pln">providedIn</span></a><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroModule</span><span class="pun">,</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HeroService</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  getHeroes</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> HEROES</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">一般来说，这和在 NgModule 本身的装饰器上配置注入器没有多少不同，主要的区别是如果 NgModule 没有用到该服务，那么它就是可以被摇树优化掉的。 对于某个提供特定服务的库而言，有些组件<em>可能</em>会希望注入器是可选的，等使用该库的应用程序来决定是否要提供该服务。</p><p translation-origin="off">This is generally no different from configuring the injector of the NgModule itself, except that the service is tree-shakable if the NgModule doesn't use it. It can be useful for a library that offers a particular service that some components <em>might</em> want to inject optionally, and leave it up to the app whether to provide the service.</p><ul><li><p translation-result="on">欲知详情，参见<a href="guide/dependency-injection-providers#tree-shakable-providers">可摇树优化的提供商</a>。</p><p translation-origin="off">Learn more about <a href="guide/dependency-injection-providers#tree-shakable-providers">tree-shakable providers</a>.</p></li></ul><h3 id="ngmodule-level-injectors" translation-result="on">@NgModule 级注入器<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#ngmodule-level-injectors"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="ngmodule-level-injectors">@NgModule-level injectors<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#ngmodule-level-injectors"><i class="material-icons">link</i></a></h3><p translation-result="on">你还可以在非根 NgModule 元数据的 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 选项中配置一个模块级的提供商，以便把该服务的范围限定到该模块一级。 这和在 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 元数据中指定一个非根模块是基本等效的，但以这种方式提供的服务无法被摇树优化掉。</p><p translation-origin="off">You can configure a provider at the module level using the <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> metadata option for a non-root NgModule, in order to limit the scope of the provider to that module. This is the equivalent of specifying the non-root module in the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> metadata, except that the service provided this way is not tree-shakable.</p><p translation-result="on">一般来说，你不必在 <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code> 中指定 <code>AppModule</code>，因为应用中的 <code>root</code> 注入器就是 <code>AppModule</code> 注入器。 不过，如果你在 <code>AppModule</code> 的 <code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> 元数据中配置了全应用级的提供商，它就会覆盖通过 <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> 配置的那一个。 你可以用这种方式来为那些供多个应用使用的服务指定非默认的提供商。</p><p translation-origin="off">You generally don't need to specify <code>AppModule</code> with <code><a href="api/core/Injectable#providedIn" class="code-anchor">providedIn</a></code>, because the app's <code>root</code> injector is the <code>AppModule</code> injector. However, if you configure a app-wide provider in the<code>@<a href="api/core/NgModule" class="code-anchor">NgModule</a>()</code> metadata for <code>AppModule</code>, it overrides one configured for <code>root</code> in the <code>@<a href="api/core/Injectable" class="code-anchor">Injectable</a>()</code> metadata. You can do this to configure a non-default provider of a service that is shared with multiple apps.</p><p translation-result="on">下面的例子中，通过把 <a href="guide/router#location-strategy">location 策略</a> 的提供商添加到 <code>AppModule</code> 的 <code>providers</code> 列表中，为路由器配置了非默认的 <a href="guide/router#location-strategy">location 策略</a>。</p><p translation-origin="off">Here is an example of the case where the component router configuration includes a non-default <a href="guide/router#location-strategy">location strategy</a> by listing its provider in the <code>providers</code> list of the <code>AppModule</code>.</p><code-example path="dependency-injection-in-action/src/app/app.module.ts" region="providers" header="src/app/app.module.ts (providers)" linenums="false" ng-version="7.0.0"><div style="display:none">providers: [ { provide: <a href="api/common/LocationStrategy" class="code-anchor">LocationStrategy</a>, useClass: <a href="api/common/HashLocationStrategy" class="code-anchor">HashLocationStrategy</a> } ]</div><header class="ng-star-inserted">src/app/app.module.ts (providers)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.module.ts (providers)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="pln">providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
  </span><span class="pun">{</span><span class="pln"> provide</span><span class="pun">:</span><span class="pln"> </span><a href="api/common/LocationStrategy" class="code-anchor"><span class="typ">LocationStrategy</span></a><span class="pun">,</span><span class="pln"> useClass</span><span class="pun">:</span><span class="pln"> </span><a href="api/common/HashLocationStrategy" class="code-anchor"><span class="typ">HashLocationStrategy</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">]</span></code>
    </pre></aio-code></code-example><a id="register-providers-component"></a><h3 id="component-level-injectors" translation-result="on">@Component 级注入器<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#component-level-injectors"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="component-level-injectors">@Component-level injectors<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#component-level-injectors"><i class="material-icons">link</i></a></h3><p translation-result="on">NgModule 中每个组件都有它自己的注入器。 通过使用 <code>@<a href="api/core/Component" class="code-anchor">Component</a></code> 元数据在组件级配置某个提供商，你可以把这个提供商的范围限定到该组件及其子组件。</p><p translation-origin="off">Individual components within an NgModule have their own injectors. You can limit the scope of a provider to a component and its children by configuring the provider at the component level using the <code>@<a href="api/core/Component" class="code-anchor">Component</a></code> metadata.</p><p translation-result="on">下面的例子是修改过的 <code>HeroesComponent</code>，它在 <code>providers</code> 数组中指定了 <code>HeroService</code>。<code>HeroService</code> 可以像该组件的实例以及任意子组件的实例提供英雄列表。</p><p translation-origin="off">The following example is a revised <code>HeroesComponent</code> that specifies <code>HeroService</code> in its <code>providers</code> array. <code>HeroService</code> can provide heroes to instances of this component, or to any child component instances.</p><code-example path="dependency-injection/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" linenums="false" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Component" class="code-anchor">Component</a> } from '@angular/core'; import { HeroService } from './hero.service'; @<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-heroes', providers: [ HeroService ], <a href="api/core/Component#template" class="code-anchor">template</a>: ` &lt;h2&gt;Heroes&lt;/h2&gt; &lt;app-hero-list&gt;&lt;/app-hero-list&gt; ` }) export class HeroesComponent { }</div><header class="ng-star-inserted">src/app/heroes/heroes.component.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/heroes/heroes.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Component" class="code-anchor"><span class="typ">Component</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroService</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero.service'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-heroes'</span><span class="pun">,</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">HeroService</span><span class="pln"> </span><span class="pun">],</span><span class="pln">
  </span><a href="api/core/Component#template" class="code-anchor"><span class="kwd">template</span></a><span class="pun">:</span><span class="pln"> </span><span class="str">`
    &lt;h2&gt;Heroes&lt;/h2&gt;
    &lt;app-hero-list&gt;&lt;/app-hero-list&gt;
  `</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HeroesComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span></code>
    </pre></aio-code></code-example><h3 id="element-injectors" translation-result="on">元素注入器<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#element-injectors"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="element-injectors">Element injectors<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#element-injectors"><i class="material-icons">link</i></a></h3><p translation-result="on">注入器本质上并不属于组件，而是 DOM 中该组件实例所附着到的元素。另一个 DOM 元素上的其它组件实例则会使用另一个注入器。</p><p translation-origin="off">An injector does not actually belong to a component, but rather to the component instance's anchor element in the DOM. A different component instance on a different DOM element uses a different injector.</p><p translation-result="on">组件是一种特殊的指令，<code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> 中的 <code>providers</code> 属性是从 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> 中继承来的。 指令也能拥有依赖，并且你也可以在它们的 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> 元数据中配置提供商。 当你使用 <code>providers</code> 属性为组件或指令配置提供商时，该提供商属于所在 DOM 元素的那个注入器。 同一个元素上的组件与指令共享同一个注入器。</p><p translation-origin="off">Components are a special type of directive, and the <code>providers</code> property of <code>@<a href="api/core/Component" class="code-anchor">Component</a>()</code> is inherited from <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code>. Directives can also have dependencies, and you can configure providers in their <code>@<a href="api/core/Directive" class="code-anchor">Directive</a>()</code> metadata. When you configure a provider for a component or directive using the <code>providers</code> property, that provider belongs to the injector for the anchor DOM element. Components and directives on the same element share an injector.</p><ul><li><p translation-result="on">欲知详情，参见<a href="https://blog.angularindepth.com/a-curios-case-of-the-host-decorator-and-element-injectors-in-angular-582562abcf0a">Angular 中的元素注入器</a>。</p><p translation-origin="off">Learn more about <a href="https://blog.angularindepth.com/a-curios-case-of-the-host-decorator-and-element-injectors-in-angular-582562abcf0a">Element Injectors in Angular</a>.</p></li></ul><h2 id="injector-bubbling" translation-result="on">注入器冒泡<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#injector-bubbling"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="injector-bubbling">Injector bubbling<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#injector-bubbling"><i class="material-icons">link</i></a></h2><p translation-result="on">考虑《英雄指南》应用的一个简单变种。它的顶层是 <code>AppComponent</code> 组件，它还有一些子组件，比如 <code>HeroesListComponent</code>。 <code>HeroesListComponent</code> 组件保存和管理着 <code>HeroTaxReturnComponent</code> 的多个实例。 下图展示了当 <code>HeroesCardComponent</code> 的三个 <code>HeroTaxReturnComponent</code> 实例同时展开时的三级组件树状态。</p><p translation-origin="off">Consider this guide's variation on the Tour of Heroes application. At the top is the <code>AppComponent</code> which has some subcomponents, such as the <code>HeroesListComponent</code>. The <code>HeroesListComponent</code> holds and manages multiple instances of the <code>HeroTaxReturnComponent</code>. The following diagram represents the state of this three-level component tree when there are three instances of <code>HeroTaxReturnComponent</code> open simultaneously.</p><figure><img src="generated/images/guide/dependency-injection/component-hierarchy.png" alt="injector tree" width="600" height="224"></figure><p translation-result="on">当一个组件申请获得一个依赖时，Angular 先尝试用该组件自己的注入器来满足它。 如果该组件的注入器没有找到对应的提供商，它就把这个申请转给它父组件的注入器来处理。 如果那个注入器也无法满足这个申请，它就继续转给它在注入器树中的父注入器。 这个申请继续往上冒泡 —— 直到 Angular 找到一个能处理此申请的注入器或者超出了组件树中的祖先位置为止。 如果超出了组件树中的祖先还未找到，Angular 就会抛出一个错误。</p><p translation-origin="off">When a component requests a dependency, Angular tries to satisfy that dependency with a provider registered in that component's own injector. If the component's injector lacks the provider, it passes the request up to its parent component's injector. If that injector can't satisfy the request, it passes the request along to the next parent injector up the tree. The requests keep bubbling up until Angular finds an injector that can handle the request or runs out of ancestor injectors. If it runs out of ancestors, Angular throws an error.</p><p translation-result="on">如果你在不同的层级上为同一个 DI 令牌注册了提供商，那么 Angular 所碰到的第一个注入器就会用来提供该依赖。 比如，如果提供商注册在该组件的本地注入器上，那么当该组件需要这个服务时，Angular 就不会去找能提供同一服务的其它提供商。</p><p translation-origin="off">If you have registered a provider for the same DI token at different levels, the first one Angular encounters is the one it uses to provide the dependency. If, for example, a provider is registered locally in the component that needs a service, Angular doesn't look for another provider of the same service.</p><div class="alert is-helpful"><p translation-result="on">你可以通过在构造函数的依赖项参数上添加参数装饰器 <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> 来限制冒泡。 当搜索提供商时，就会在组件宿主元素的注入器处停下。</p><p translation-origin="off">You can cap the bubbling by adding the <code>@<a href="api/core/Host" class="code-anchor">Host</a>()</code> parameter decorator on the dependant-service parameter in a component's constructor. The hunt for providers stops at the injector for the host element of the component.</p><ul><li><p translation-result="on">参见这个同时使用 <code>@<a href="api/core/Host" class="code-anchor">Host</a></code> 和 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a></code> 的<a href="guide/dependency-injection-in-action#qualify-dependency-lookup">例子</a>，另一个参数装饰器 <code>@<a href="api/core/Optional" class="code-anchor">Optional</a></code> 让你能在没有找到提供商时把参数置为 null。</p><p translation-origin="off">See an <a href="guide/dependency-injection-in-action#qualify-dependency-lookup">example</a> of using <code>@<a href="api/core/Host" class="code-anchor">Host</a></code> together with <code>@<a href="api/core/Optional" class="code-anchor">Optional</a></code>, another parameter decorator that lets you handle the null case if no provider is found.</p></li><li><p translation-result="on">到 <a href="https://blog.angularindepth.com/a-curios-case-of-the-host-decorator-and-element-injectors-in-angular-582562abcf0a"><code>@Host</code> 装饰器与元素注入器</a> 中了解更多。</p><p translation-origin="off">Learn more about the <a href="https://blog.angularindepth.com/a-curios-case-of-the-host-decorator-and-element-injectors-in-angular-582562abcf0a"><code>@Host</code> decorator and Element Injectors</a>.</p></li></ul></div><p translation-result="on">如果你只在顶级的根注入器（通常为根模块 <code>AppModule</code>）上注册提供商，则注入器树看起来就是扁平的。 无论你使用 <code>bootstrapModule</code> 方法配置它，还是在自己的服务中使用 <code>root</code> 注册了这些提供商，所有的请求都会冒泡到根注入器上。</p><p translation-origin="off">If you only register providers with the root injector at the top level (typically the root <code>AppModule</code>), the tree of injectors appears to be flat. All requests bubble up to the root injector, whether you configured it with the <code>bootstrapModule</code> method, or registered all providers with <code>root</code> in their own services.</p><a id="component-injectors"></a><h2 id="component-injectors" translation-result="on">组件注入器<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#component-injectors"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="component-injectors">Component injectors<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#component-injectors"><i class="material-icons">link</i></a></h2><p translation-result="on">在不同层次上重新配置一个或多个提供商的能力，开启了一些既有趣又有用的可能性。 本指南中的例子提供了一些你可能会用到它的场景。</p><p translation-origin="off">The ability to configure one or more providers at different levels opens up interesting and useful possibilities. The guide sample offers some scenarios where you might want to do so.</p><h3 id="scenario-service-isolation" translation-result="on">场景：服务隔离<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-service-isolation"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="scenario-service-isolation">Scenario: service isolation<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-service-isolation"><i class="material-icons">link</i></a></h3><p translation-result="on">出于架构方面的考虑，可能会让你决定把一个服务限制到只能在它所属的那个应用域中访问。</p><p translation-origin="off">Architectural reasons may lead you to restrict access to a service to the application domain where it belongs.</p><p translation-result="on">比如，这个例子中包括一个用于显示反派列表的 <code>VillainsListComponent</code>，它会从 <code>VillainsService</code> 中获得反派列表数据。</p><p translation-origin="off">For example, the guide sample includes a <code>VillainsListComponent</code> that displays a list of villains. It gets those villains from a <code>VillainsService</code>.</p><p translation-result="on">如果你在根模块 <code>AppModule</code> 中（也就是你注册 <code>HeroesService</code> 的地方）提供 <code>VillainsService</code>，就会让应用中的任何地方都能访问到 <code>VillainsService</code>，包括针对英雄的工作流。如果你稍后修改了 <code>VillainsService</code>，就可能破坏了英雄组件中的某些地方。在根模块 <code>AppModule</code> 中提供该服务将会引入此风险。</p><p translation-origin="off">If you provide <code>VillainsService</code> in the root <code>AppModule</code> (where you registered the <code>HeroesService</code>), that would make the <code>VillainsService</code> available everywhere in the application, including the <em>Hero</em> workflows. If you later modified the <code>VillainsService</code>, you could break something in a hero component somewhere. Providing the service in the root <code>AppModule</code> creates that risk.</p><p translation-result="on">该怎么做呢？你可以在 <code>VillainsListComponent</code> 的 <code>providers</code> 元数据中提供 <code>VillainsService</code>，就像这样：</p><p translation-origin="off">Instead, you can provide the <code>VillainsService</code> in the <code>providers</code> metadata of the <code>VillainsListComponent</code> like this:</p><code-example path="hierarchical-dependency-injection/src/app/villains-list.component.ts" linenums="false" header="src/app/villains-list.component.ts (metadata)" region="metadata" ng-version="7.0.0"><div style="display:none">@<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-villains-list', templateUrl: './villains-list.component.html', providers: [ VillainsService ] })</div><header class="ng-star-inserted">src/app/villains-list.component.ts (metadata)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/villains-list.component.ts (metadata)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-villains-list'</span><span class="pun">,</span><span class="pln">
  templateUrl</span><span class="pun">:</span><span class="pln"> </span><span class="str">'./villains-list.component.html'</span><span class="pun">,</span><span class="pln">
  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">VillainsService</span><span class="pln"> </span><span class="pun">]</span><span class="pln">
</span><span class="pun">})</span></code>
    </pre></aio-code></code-example><p translation-result="on">在 <code>VillainsListComponent</code> 的元数据中而不是其它地方提供 <code>VillainsService</code> 服务，该服务就会只在 <code>VillainsListComponent</code> 及其子组件树中可用。 它仍然是单例，但是这个单例只存在于<em>反派（villain）</em>这个领域中。</p><p translation-origin="off">By providing <code>VillainsService</code> in the <code>VillainsListComponent</code> metadata and nowhere else, the service becomes available only in the <code>VillainsListComponent</code> and its sub-component tree. It's still a singleton, but it's a singleton that exist solely in the <em>villain</em> domain.</p><p translation-result="on">现在，你可以确信英雄组件不会访问它，因此减少了犯错误的机会。</p><p translation-origin="off">Now you know that a hero component can't access it. You've reduced your exposure to error.</p><h3 id="scenario-multiple-edit-sessions" translation-result="on">场景：多重编辑会话<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="scenario-multiple-edit-sessions">Scenario: multiple edit sessions<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions"><i class="material-icons">link</i></a></h3><p translation-result="on">很多应用允许用户同时进行多个任务。 比如，在纳税申报应用中，申报人可以打开多个报税单，随时可能从一个切换到另一个。</p><p translation-origin="off">Many applications allow users to work on several open tasks at the same time. For example, in a tax preparation application, the preparer could be working on several tax returns, switching from one to the other throughout the day.</p><p translation-result="on">本章要示范的场景仍然是基于《英雄指南》的。 想象一个外层的 <code>HeroListComponent</code>，它显示一个超级英雄的列表。</p><p translation-origin="off">This guide demonstrates that scenario with an example in the Tour of Heroes theme. Imagine an outer <code>HeroListComponent</code> that displays a list of super heroes.</p><p translation-result="on">要打开一个英雄的报税单，申报者点击英雄名，它就会打开一个组件来编辑那个申报单。 每个选中的申报单都会在自己的组件中打开，并且可以同时打开多个申报单。</p><p translation-origin="off">To open a hero's tax return, the preparer clicks on a hero name, which opens a component for editing that return. Each selected hero tax return opens in its own component and multiple returns can be open at the same time.</p><p translation-result="on">每个报税单组件都有下列特征：</p><p translation-origin="off">Each tax return component has the following characteristics:</p><ul><li><p translation-result="on">属于它自己的报税单会话。</p><p translation-origin="off">Is its own tax return editing session.</p></li><li><p translation-result="on">可以修改一个报税单，而不会影响另一个组件中的申报单。</p><p translation-origin="off">Can change a tax return without affecting a return in another component.</p></li><li><p translation-result="on">能把所做的修改保存到它的报税单中，或者放弃它们。</p><p translation-origin="off">Has the ability to save the changes to its tax return or cancel them.</p></li></ul><figure><img src="generated/images/guide/dependency-injection/hid-heroes-anim.gif" alt="Heroes in action" width="500" height="384"></figure><p translation-result="on">假设 <code>HeroTaxReturnComponent</code> 还有一些管理并还原这些更改的逻辑。 这对于简单的报税单来说是很容易的。 不过，在现实世界中，报税单的数据模型非常复杂，对这些修改的管理可能不得不投机取巧。 你可以把这种管理任务委托给一个辅助服务，就像这个例子中所做的。</p><p translation-origin="off">Suppose that the <code>HeroTaxReturnComponent</code> has logic to manage and restore changes. That would be a pretty easy task for a simple hero tax return. In the real world, with a rich tax return data model, the change management would be tricky. You could delegate that management to a helper service, as this example does.</p><p translation-result="on">这是一个报税单服务 <code>HeroTaxReturnService</code>。 它缓存了单条 <code>HeroTaxReturn</code>，用于跟踪那个申报单的变更，并且可以保存或还原它。 它还委托给了全应用级的单例服务 <code>HeroService</code>，它是通过依赖注入机制取得的。</p><p translation-origin="off">Here is the <code>HeroTaxReturnService</code>. It caches a single <code>HeroTaxReturn</code>, tracks changes to that return, and can save or restore it. It also delegates to the application-wide singleton <code>HeroService</code>, which it gets by injection.</p><code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.service.ts" header="src/app/hero-tax-return.service.ts" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Injectable" class="code-anchor">Injectable</a> } from '@angular/core'; import { HeroTaxReturn } from './hero'; import { HeroesService } from './heroes.service'; @<a href="api/core/Injectable" class="code-anchor">Injectable</a>() export class HeroTaxReturnService { private currentTaxReturn: HeroTaxReturn; private originalTaxReturn: HeroTaxReturn; constructor(private heroService: HeroesService) { } set taxReturn (htr: HeroTaxReturn) { this.originalTaxReturn = htr; this.currentTaxReturn = htr.clone(); } get taxReturn (): HeroTaxReturn { return this.currentTaxReturn; } restoreTaxReturn() { this.taxReturn = this.originalTaxReturn; } saveTaxReturn() { this.taxReturn = this.currentTaxReturn; this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe(); } }</div><header class="ng-star-inserted">src/app/hero-tax-return.service.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/hero-tax-return.service.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><ol class="linenums"><li class="L0"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Injectable" class="code-anchor"><span class="typ">Injectable</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln">    </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span></li><li class="L1"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero'</span><span class="pun">;</span></li><li class="L2"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroesService</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./heroes.service'</span><span class="pun">;</span></li><li class="L3"><span class="pln">&nbsp;</span></li><li class="L4"><span class="lit">@</span><a href="api/core/Injectable" class="code-anchor"><span class="lit">Injectable</span></a><span class="pun">()</span></li><li class="L5"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">{</span></li><li class="L6"><span class="pln">  </span><span class="kwd">private</span><span class="pln"> currentTaxReturn</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">;</span></li><li class="L7"><span class="pln">  </span><span class="kwd">private</span><span class="pln"> originalTaxReturn</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">;</span></li><li class="L8"><span class="pln">&nbsp;</span></li><li class="L9"><span class="pln">  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">private</span><span class="pln"> heroService</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroesService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span></li><li class="L0"><span class="pln">&nbsp;</span></li><li class="L1"><span class="pln">  </span><span class="kwd">set</span><span class="pln"> taxReturn </span><span class="pun">(</span><span class="pln">htr</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></li><li class="L2"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">originalTaxReturn </span><span class="pun">=</span><span class="pln"> htr</span><span class="pun">;</span></li><li class="L3"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn  </span><span class="pun">=</span><span class="pln"> htr</span><span class="pun">.</span><span class="pln">clone</span><span class="pun">();</span></li><li class="L4"><span class="pln">  </span><span class="pun">}</span></li><li class="L5"><span class="pln">&nbsp;</span></li><li class="L6"><span class="pln">  </span><span class="kwd">get</span><span class="pln"> taxReturn </span><span class="pun">():</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">{</span></li><li class="L7"><span class="pln">    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn</span><span class="pun">;</span></li><li class="L8"><span class="pln">  </span><span class="pun">}</span></li><li class="L9"><span class="pln">&nbsp;</span></li><li class="L0"><span class="pln">  restoreTaxReturn</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></li><li class="L1"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">taxReturn </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">originalTaxReturn</span><span class="pun">;</span></li><li class="L2"><span class="pln">  </span><span class="pun">}</span></li><li class="L3"><span class="pln">&nbsp;</span></li><li class="L4"><span class="pln">  saveTaxReturn</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></li><li class="L5"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">taxReturn </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn</span><span class="pun">;</span></li><li class="L6"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroService</span><span class="pun">.</span><span class="pln">saveTaxReturn</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">currentTaxReturn</span><span class="pun">).</span><span class="pln">subscribe</span><span class="pun">();</span></li><li class="L7"><span class="pln">  </span><span class="pun">}</span></li><li class="L8"><span class="pun">}</span></li></ol></code>
    </pre></aio-code></code-example><p translation-result="on">下面是正在使用它的 <code>HeroTaxReturnComponent</code> 组件。</p><p translation-origin="off">Here is the <code>HeroTaxReturnComponent</code> that makes use of it.</p><code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" header="src/app/hero-tax-return.component.ts" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Component" class="code-anchor">Component</a>, <a href="api/core/EventEmitter" class="code-anchor">EventEmitter</a>, <a href="api/core/Input" class="code-anchor">Input</a>, <a href="api/core/Output" class="code-anchor">Output</a> } from '@angular/core'; import { HeroTaxReturn } from './hero'; import { HeroTaxReturnService } from './hero-tax-return.service'; @<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-hero-tax-return', templateUrl: './hero-tax-return.component.html', <a href="api/core/Component#styleUrls" class="code-anchor">styleUrls</a>: [ './hero-tax-return.component.css' ], providers: [ HeroTaxReturnService ] }) export class HeroTaxReturnComponent { <a href="api/common/http/HttpErrorResponse#message" class="code-anchor">message</a> = ''; @<a href="api/core/Output" class="code-anchor">Output</a>() close = new <a href="api/core/EventEmitter" class="code-anchor">EventEmitter</a>&lt;void&gt;(); get taxReturn(): HeroTaxReturn { return this.heroTaxReturnService.taxReturn; } @<a href="api/core/Input" class="code-anchor">Input</a>() set taxReturn (htr: HeroTaxReturn) { this.heroTaxReturnService.taxReturn = htr; } constructor(private heroTaxReturnService: HeroTaxReturnService) { } onCanceled() { this.flashMessage('Canceled'); this.heroTaxReturnService.restoreTaxReturn(); }; onClose() { this.close.emit(); }; onSaved() { this.flashMessage('Saved'); this.heroTaxReturnService.saveTaxReturn(); } flashMessage(msg: string) { this.message = msg; setTimeout(() =&gt; this.message = '', 500); } }</div><header class="ng-star-inserted">src/app/hero-tax-return.component.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/hero-tax-return.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><ol class="linenums"><li class="L0"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Component" class="code-anchor"><span class="typ">Component</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/EventEmitter" class="code-anchor"><span class="typ">EventEmitter</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/Input" class="code-anchor"><span class="typ">Input</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/Output" class="code-anchor"><span class="typ">Output</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span></li><li class="L1"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">}</span><span class="pln">        </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero'</span><span class="pun">;</span></li><li class="L2"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'./hero-tax-return.service'</span><span class="pun">;</span></li><li class="L3"><span class="pln">&nbsp;</span></li><li class="L4"><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span></li><li class="L5"><span class="pln">  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-hero-tax-return'</span><span class="pun">,</span></li><li class="L6"><span class="pln">  templateUrl</span><span class="pun">:</span><span class="pln"> </span><span class="str">'./hero-tax-return.component.html'</span><span class="pun">,</span></li><li class="L7"><span class="pln">  </span><a href="api/core/Component#styleUrls" class="code-anchor"><span class="pln">styleUrls</span></a><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="str">'./hero-tax-return.component.css'</span><span class="pln"> </span><span class="pun">],</span></li><li class="L8"><span class="pln">  providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">]</span></li><li class="L9"><span class="pun">})</span></li><li class="L0"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HeroTaxReturnComponent</span><span class="pln"> </span><span class="pun">{</span></li><li class="L1"><span class="pln">  </span><a href="api/common/http/HttpErrorResponse#message" class="code-anchor"><span class="pln">message</span></a><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">''</span><span class="pun">;</span></li><li class="L2"><span class="pln">&nbsp;</span></li><li class="L3"><span class="pln">  </span><span class="lit">@</span><a href="api/core/Output" class="code-anchor"><span class="lit">Output</span></a><span class="pun">()</span><span class="pln"> close </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><a href="api/core/EventEmitter" class="code-anchor"><span class="typ">EventEmitter</span></a><span class="str">&lt;void&gt;</span><span class="pun">();</span></li><li class="L4"><span class="pln">&nbsp;</span></li><li class="L5"><span class="pln">  </span><span class="kwd">get</span><span class="pln"> taxReturn</span><span class="pun">():</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pln"> </span><span class="pun">{</span></li><li class="L6"><span class="pln">    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">taxReturn</span><span class="pun">;</span></li><li class="L7"><span class="pln">  </span><span class="pun">}</span></li><li class="L8"><span class="pln">&nbsp;</span></li><li class="L9"><span class="pln">  </span><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">()</span></li><li class="L0"><span class="pln">  </span><span class="kwd">set</span><span class="pln"> taxReturn </span><span class="pun">(</span><span class="pln">htr</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturn</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></li><li class="L1"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">taxReturn </span><span class="pun">=</span><span class="pln"> htr</span><span class="pun">;</span></li><li class="L2"><span class="pln">  </span><span class="pun">}</span></li><li class="L3"><span class="pln">&nbsp;</span></li><li class="L4"><span class="pln">  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">private</span><span class="pln"> heroTaxReturnService</span><span class="pun">:</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span></li><li class="L5"><span class="pln">&nbsp;</span></li><li class="L6"><span class="pln">  onCanceled</span><span class="pun">()</span><span class="pln">  </span><span class="pun">{</span></li><li class="L7"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">flashMessage</span><span class="pun">(</span><span class="str">'Canceled'</span><span class="pun">);</span></li><li class="L8"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">restoreTaxReturn</span><span class="pun">();</span></li><li class="L9"><span class="pln">  </span><span class="pun">};</span></li><li class="L0"><span class="pln">&nbsp;</span></li><li class="L1"><span class="pln">  onClose</span><span class="pun">()</span><span class="pln">  </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">close</span><span class="pun">.</span><span class="pln">emit</span><span class="pun">();</span><span class="pln"> </span><span class="pun">};</span></li><li class="L2"><span class="pln">&nbsp;</span></li><li class="L3"><span class="pln">  onSaved</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></li><li class="L4"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">flashMessage</span><span class="pun">(</span><span class="str">'Saved'</span><span class="pun">);</span></li><li class="L5"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">heroTaxReturnService</span><span class="pun">.</span><span class="pln">saveTaxReturn</span><span class="pun">();</span></li><li class="L6"><span class="pln">  </span><span class="pun">}</span></li><li class="L7"><span class="pln">&nbsp;</span></li><li class="L8"><span class="pln">  flashMessage</span><span class="pun">(</span><span class="pln">msg</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></li><li class="L9"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">message </span><span class="pun">=</span><span class="pln"> msg</span><span class="pun">;</span></li><li class="L0"><span class="pln">    setTimeout</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">message </span><span class="pun">=</span><span class="pln"> </span><span class="str">''</span><span class="pun">,</span><span class="pln"> </span><span class="lit">500</span><span class="pun">);</span></li><li class="L1"><span class="pln">  </span><span class="pun">}</span></li><li class="L2"><span class="pun">}</span></li></ol></code>
    </pre></aio-code></code-example><p translation-result="on">通过输入属性可以得到<em>要编辑的报税单</em>，这个属性被实现成了读取器（getter）和设置器（setter）。 设置器根据传进来的报税单初始化了组件自己的 <code>HeroTaxReturnService</code> 实例。 读取器总是返回该服务所存英雄的当前状态。 组件也会请求该服务来保存或还原这个报税单。</p><p translation-origin="off">The <em>tax-return-to-edit</em> arrives via the input property which is implemented with getters and setters. The setter initializes the component's own instance of the <code>HeroTaxReturnService</code> with the incoming return. The getter always returns what that service says is the current state of the hero. The component also asks the service to save and restore this tax return.</p><p translation-result="on">但如果该服务是一个全应用范围的单例就不行了。 每个组件就都会共享同一个服务实例，每个组件也都会覆盖属于其他英雄的报税单。</p><p translation-origin="off">This won't work if the service is an application-wide singleton. Every component would share the same service instance, and each component would overwrite the tax return that belonged to another hero.</p><p translation-result="on">要防止这一点，我们就要在 <code>HeroTaxReturnComponent</code> 元数据的 <code>providers</code> 属性中配置组件级的注入器，来提供该服务。</p><p translation-origin="off">To prevent this, we configure the component-level injector of <code>HeroTaxReturnComponent</code> to provide the service, using the <code>providers</code> property in the component metadata.</p><code-example path="hierarchical-dependency-injection/src/app/hero-tax-return.component.ts" linenums="false" header="src/app/hero-tax-return.component.ts (providers)" region="providers" ng-version="7.0.0"><div style="display:none">providers: [ HeroTaxReturnService ]</div><header class="ng-star-inserted">src/app/hero-tax-return.component.ts (providers)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/hero-tax-return.component.ts (providers)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="pln">providers</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="typ">HeroTaxReturnService</span><span class="pln"> </span><span class="pun">]</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>HeroTaxReturnComponent</code> 有它自己的 <code>HeroTaxReturnService</code> 提供商。 回忆一下，每个组件的<em>实例</em>都有它自己的注入器。 在组件级提供服务可以确保组件的<em>每个</em>实例都得到一个自己的、私有的服务实例，而报税单也不会再被意外覆盖了。</p><p translation-origin="off">The <code>HeroTaxReturnComponent</code> has its own provider of the <code>HeroTaxReturnService</code>. Recall that every component <em>instance</em> has its own injector. Providing the service at the component level ensures that <em>every</em> instance of the component gets its own, private instance of the service, and no tax return gets overwritten.</p><div class="alert is-helpful"><p translation-result="on">该场景代码中的其它部分依赖另一些 Angular 的特性和技术，你将会在本文档的其它章节学到。 你可以到<live-example ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html" title="在线例子">在线例子</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>查看代码和下载它。</p><p translation-origin="off">The rest of the scenario code relies on other Angular features and techniques that you can learn about elsewhere in the documentation. You can review it and download it from the<live-example ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html" title="在线例子">在线例子</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>.</p></div><h3 id="scenario-specialized-providers" translation-result="on">场景：专门的提供商<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-specialized-providers"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="scenario-specialized-providers">Scenario: specialized providers<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/hierarchical-dependency-injection#scenario-specialized-providers"><i class="material-icons">link</i></a></h3><p translation-result="on">在其它层级重新提供服务的另一个理由，是在组件树的深层中把该服务替换为一个<em>更专门化的</em>实现。</p><p translation-origin="off">Another reason to re-provide a service at another level is to substitute a <em>more specialized</em> implementation of that service, deeper in the component tree.</p><p translation-result="on">考虑一个依赖于一系列服务的 Car 组件。 假设你在根注入器（代号 A）中配置了<em>通用的</em>提供商：<code>CarService</code>、<code>EngineService</code> 和 <code>TiresService</code>。</p><p translation-origin="off">Consider a Car component that depends on several services. Suppose you configured the root injector (marked as A) with <em>generic</em> providers for <code>CarService</code>, <code>EngineService</code> and <code>TiresService</code>.</p><p translation-result="on">你创建了一个车辆组件（A），它显示一个从另外三个通用服务构造出的车辆。</p><p translation-origin="off">You create a car component (A) that displays a car constructed from these three generic services.</p><p translation-result="on">然后，你创建一个子组件（B），它为 <code>CarService</code> 和 <code>EngineService</code> 定义了自己<em>特有的</em>提供商，它们具有适用于组件 B 的特有能力。</p><p translation-origin="off">Then you create a child component (B) that defines its own, <em>specialized</em> providers for <code>CarService</code> and <code>EngineService</code> that have special capabilities suitable for whatever is going on in component (B).</p><p translation-result="on">组件 B 是另一个组件 C 的父组件，而组件 C 又定义了自己的，<em>更特殊的</em><code>CarService</code> 提供商。</p><p translation-origin="off">Component (B) is the parent of another component (C) that defines its own, even <em>more specialized</em> provider for <code>CarService</code>.</p><figure><img src="generated/images/guide/dependency-injection/car-components.png" alt="car components" width="338" height="201"></figure><p translation-result="on">在幕后，每个组件都有自己的注入器，这个注入器带有为组件本身准备的 0 个、1 个或多个提供商。</p><p translation-origin="off">Behind the scenes, each component sets up its own injector with zero, one, or more providers defined for that component itself.</p><p translation-result="on">当你在最深层的组件 C 解析 <code>Car</code> 的实例时，它使用注入器 C 解析生成了一个 <code>Car</code> 的实例，使用注入器 B 解析了 <code>Engine</code>，而 <code>Tires</code> 则是由根注入器 A 解析的。</p><p translation-origin="off">When you resolve an instance of <code>Car</code> at the deepest component (C), its injector produces an instance of <code>Car</code> resolved by injector (C) with an <code>Engine</code> resolved by injector (B) and <code>Tires</code> resolved by the root injector (A).</p><figure><img src="generated/images/guide/dependency-injection/injector-tree.png" alt="car injector tree" width="600" height="248"></figure><div class="alert is-helpful"><p translation-result="on"><em>车辆</em>场景下的代码位于 <code>car.components.ts</code> 和 <code>car.services.ts</code> 文件中，这个例子你可以在<live-example ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html" title="在线例子">在线例子</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>查看和下载。</p><p translation-origin="off">The code for this <em>cars</em> scenario is in the <code>car.components.ts</code> and <code>car.services.ts</code> files of the sample which you can review and download from the<live-example ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/hierarchical-dependency-injection/stackblitz.html" title="在线例子">在线例子</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/hierarchical-dependency-injection/hierarchical-dependency-injection.zip">下载范例</a></span></span></span></live-example>.</p></div></div></div></aio-doc-viewer></main></mat-sidenav-content></mat-sidenav-container><div class="toc-container no-print ng-star-inserted"><aio-lazy-ce selector="aio-toc"><aio-toc ng-version="7.0.0"><div class="toc-inner no-print collapsed ng-star-inserted"><ul class="toc-list"><li title="多级依赖注入器link" class="h1 ng-star-inserted active"><a href="guide/hierarchical-dependency-injection#hierarchical-dependency-injectors">多级依赖注入器</a></li><li title="在哪里配置提供商link" class="h2 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#where-to-configure-providers">在哪里配置提供商</a></li><li title="在 @Injectable 级进行配置link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#injectable-level-configuration">在 @Injectable 级进行配置</a></li><li title="@NgModule 级注入器link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#ngmodule-level-injectors">@NgModule 级注入器</a></li><li title="@Component 级注入器link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#component-level-injectors">@Component 级注入器</a></li><li title="元素注入器link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#element-injectors">元素注入器</a></li><li title="注入器冒泡link" class="h2 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#injector-bubbling">注入器冒泡</a></li><li title="组件注入器link" class="h2 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#component-injectors">组件注入器</a></li><li title="场景：服务隔离link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#scenario-service-isolation">场景：服务隔离</a></li><li title="场景：多重编辑会话link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#scenario-multiple-edit-sessions">场景：多重编辑会话</a></li><li title="场景：专门的提供商link" class="h3 ng-star-inserted"><a href="guide/hierarchical-dependency-injection#scenario-specialized-providers">场景：专门的提供商</a></li></ul></div></aio-toc></aio-lazy-ce></div><footer class="no-print"><aio-footer><div class="grid-fluid"><div class="footer-block ng-star-inserted"><h3>资源</h3><ul><li class="ng-star-inserted"><a class="link" href="about" title="Angular 贡献者。">关于</a></li><li class="ng-star-inserted"><a class="link" href="resources" title="网络上的 Angular 工具、培训、博客等">资源列表</a></li><li class="ng-star-inserted"><a class="link" href="presskit" title="我们的联系方式、LOGO 和品牌">宣传资料</a></li><li class="ng-star-inserted"><a class="link" href="https://blog.angular.io/" title="Angular 官方博客">博客</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>帮助</h3><ul><li class="ng-star-inserted"><a class="link" href="https://stackoverflow.com/questions/tagged/angular" title="Stack Overflow: 这里的社区会回答你关于 Angular 的技术问题">Stack Overflow</a></li><li class="ng-star-inserted"><a class="link" href="https://gitter.im/angular/angular" title="和老鸟聊 Angular">Gitter</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/angular/issues" title="在 github 上报告问题和建议。">报告问题</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md" title="让我们彼此尊重">行为规范</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>社区</h3><ul><li class="ng-star-inserted"><a class="link" href="events" title="Post issues and suggestions on github.">活动</a></li><li class="ng-star-inserted"><a class="link" href="http://www.meetup.com/topics/angularjs/" title="参加聚会，向别的开发人员学习">聚会</a></li><li class="ng-star-inserted"><a class="link" href="https://twitter.com/angular" title="Twitter">Twitter</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/angular" title="GitHub">GitHub</a></li><li class="ng-star-inserted"><a class="link" href="contribute" title="向 Angular 做贡献">做贡献</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>多语言</h3><ul><li class="ng-star-inserted"><a class="link" href="https://angular.io/" title="English Version.">English Version</a></li><li class="ng-star-inserted"><a class="link" href="https://angular.jp/" title="日本語版">日本語版</a></li><li class="ng-star-inserted"><a class="link" href="https://angular.kr/" title="한국어">한국어</a></li></ul></div></div><p>Super-powered by Google ©2010-2019. 代码授权方式：<a href="license" title="License text">MIT-style License</a>. 文档授权方式：<a href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.</p><p>当前版本：8.0.0-build.95+sha.43aadf1.</p></aio-footer></footer><mat-icon class="cdk-visually-hidden mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">&nbsp;</mat-icon></aio-shell><noscript><div class="background-sky hero"></div><section id="intro" style="text-shadow:1px 1px #1976d2"><div class="hero-logo"><img src="assets/images/logos/angular/angular.svg" width="250" height="250" alt="Angular"></div><div class="homepage-container"><div class="hero-headline">一套框架，多种平台<br>移动 &amp; 桌面</div></div></section><h2 style="color:red;margin-top:40px;position:relative;text-align:center;text-shadow:1px 1px #fafafa"><b><i>该网站需要浏览器支持 JavaScript</i></b></h2></noscript><script src="runtime.fa3355727d5250409e08.js"></script><script src="polyfills.a2efc1c1a62312ff1f80.js"></script><script src="main.02884fe4cde5ede2ec4e.js"></script><div class="cdk-live-announcer-element cdk-visually-hidden" aria-atomic="true" aria-live="polite"></div></body></html>